import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;

public class SortedMapMain {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		List<String> keys = new ArrayList<String>(Arrays.asList(new String[] { "1", "2", "3", "4" , "5" }));
		List<String> values = new ArrayList<String>(Arrays.asList(new String[] { "d", "c", "a", "b" , "c" }));
		Map<String, String> map = new HashMap<String, String>();
		for ( int i = 0 ; i < keys.size() ; i++ ) {
			map.put( keys.get(i), values.get(i) );
		}

		System.out.println( m1( map ) );
		System.out.println( m2( map ) );
		System.out.println( m3( map ) );
		System.out.println( m4( map ) );
		System.out.println( m5( map ) );
	}

	// elimina duplicados
	private static Map<String, String> m1( final Map<String, String> map ) {

		SortedMap<String, String> sortedMap = new TreeMap<String, String>(
			new Comparator<String>() {
				@Override
				public int compare(String key1, String key2) {
					return map.get(key1).compareTo( map.get(key2) );
				}
		});

		sortedMap.putAll( map );

		return sortedMap;
	}

	private static Map<String, String> m2( Map<String, String> map ) {

		List<Entry<String, String>> sortedList = new ArrayList<Entry<String, String>>( map.entrySet() );
		Collections.sort( sortedList, new Comparator<Entry<String, String>>() {
			public int compare(Entry<String, String> lhs, Entry<String, String> rhs) {
				return lhs.getValue().compareTo( rhs.getValue() );
			}
		});

		Map<String, String> sortedMap = new LinkedHashMap<String, String>();
		for ( Entry<String, String> entry : sortedList ) {
			sortedMap.put( entry.getKey(), entry.getValue() );
		}

		return sortedMap;
	}

	private static Map<String, String> m3( Map<String, String> map ) {

		List<String> sortedList = new ArrayList<String>();
		for ( Entry<String, String> entry : map.entrySet() ) {
			sortedList.add( entry.getValue()+"#"+entry.getKey() );
		}

		Collections.sort( sortedList );

		Map<String, String> sortedMap = new LinkedHashMap<String, String>();
		for ( String value : sortedList ) {
			String[] element = value.split("#");
			sortedMap.put( element[1], element[0] );
		}

		return sortedMap;
	}

	// elimina duplicados
	private static Map<String, String> m4( Map<String, String> map ) {

		List<String> mapKeys = new ArrayList<String>( map.keySet() );
		List<String> mapValues = new ArrayList<String>( map.values() );

		SortedSet<String> sortedSet = new TreeSet<String>( mapValues );

		Map<String, String> sortedMap = new LinkedHashMap<String, String>();
		for( String value : sortedSet ) {
			sortedMap.put( mapKeys.get( mapValues.indexOf( value ) ), value );
		}

		return sortedMap;
	}

	// elimina duplicados
	private static Map<String, String> m5( Map<String, String> map ) {

		List<String> mapKeys = new ArrayList<String>( map.keySet() );
		List<String> mapValues = new ArrayList<String>( map.values() );

		List<String> sortedList = new ArrayList<String>( map.values() );
		Collections.sort( sortedList );

		Map<String, String> sortedMap = new LinkedHashMap<String, String>();
		for( String value : sortedList ) {
			sortedMap.put( mapKeys.get( mapValues.indexOf( value ) ), value );
		}

		return sortedMap;
	}
}